package utils

import (
	"bytes"
	"errors"
	"math/rand"
	"regexp"
	"strings"

	"github.com/goccy/go-json"
)

// JSONMarshal marshals v to JSON without escaping HTML
func JSONMarshal(v interface{}) ([]byte, error) {
	if v == nil {
		return nil, errors.New("v is nil")
	}
	var buf bytes.Buffer
	encoder := json.NewEncoder(&buf)
	encoder.SetEscapeHTML(false)
	err := encoder.Encode(v)
	if err != nil {
		return nil, err
	}
	// Remove the trailing newline added by encoder.Encode
	return bytes.TrimSpace(buf.Bytes()), nil
}

func ParseMap(data []byte) (map[string]interface{}, error) {
	var result map[string]interface{}
	err := json.Unmarshal(data, &result)
	if err != nil {
		return nil, err
	}
	return result, nil
}

func RandomString(length int) string {
	// 随机字符串
	const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
	b := make([]byte, length)
	for i := range b {
		b[i] = letterBytes[rand.Intn(len(letterBytes))]
	}
	return string(b)
}

// camelToSnake converts CamelCase to snake_case
func CamelToSnake(s string) string {
	// Insert an underscore before each uppercase letter (except the first one)
	re := regexp.MustCompile("([a-z])([A-Z])")
	snake := re.ReplaceAllString(s, "${1}_${2}")

	// Convert the entire string to lowercase
	return strings.ToLower(snake)
}
